/**
 * Copyright 2009 cestum.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.cestum.cave.ui.components {
	import spark.components.Group;
	import spark.components.Panel;
	import spark.layouts.supportClasses.LayoutBase;
	import mx.utils.BitFlagUtil;
	/**
	 * An extension of Panel to support ButtonBar 
	 **/
	public class CavePanel extends Panel	{
		/**
		 *  @private
		 */
		private static const LINKBAR_PROPERTY_FLAG:uint = 1 << 0;
		/**
		 *  @private
		 */
		private static const LAYOUT_PROPERTY_FLAG:uint = 1 << 1;
		
		public function CavePanel()
		{
			super();
		}
		
		/**
		 *  @private
		 *  Several properties are proxied to controlBarGroup.  However, when controlBarGroup
		 *  is not around, we need to store values set on SkinnableContainer.  This object 
		 *  stores those values.  If controlBarGroup is around, the values are stored 
		 *  on the controlBarGroup directly.  However, we need to know what values 
		 *  have been set by the developer on the SkinnableContainer (versus set on 
		 *  the controlBarGroup or defaults of the controlBarGroup) as those are values 
		 *  we want to carry around if the controlBarGroup changes (via a new skin). 
		 *  In order to store this info effeciently, controlBarGroupProperties becomes 
		 *  a uint to store a series of BitFlags.  These bits represent whether a 
		 *  property has been explicitely set on this SkinnableContainer.  When the 
		 *  controlBarGroup is not around, controlBarGroupProperties is a typeless 
		 *  object to store these proxied properties.  When controlBarGroup is around,
		 *  controlBarGroupProperties stores booleans as to whether these properties 
		 *  have been explicitely set or not.
		 */
		private var linkBarGroupProperties:Object = {};
		
		//----------------------------------
		//  controlBarGroup
		//---------------------------------- 
		
		[SkinPart(required="false")]
		
		/**
		 *  The skin part that defines the appearance of the 
		 *  control bar in the container.
		 *
		 *  @see spark.skins.spark.PanelSkin
		 *  
		 *  @langversion 3.0
		 *  @playerversion Flash 10
		 *  @playerversion AIR 1.5
		 *  @productversion Flex 4
		 */
		public var linkBarGroup:Group;
		
		//----------------------------------
		//  controlBarContent
		//---------------------------------- 
		
		[ArrayElementType("mx.core.IVisualElement")]
		
		/**
		 *  The set of items that become the content of
		 *  the controlBarGroup
		 *  
		 *  @langversion 3.0
		 *  @playerversion Flash 10
		 *  @playerversion AIR 1.5
		 *  @productversion Flex 4
		 */
		public function set linkBarContent(value:Array):void
		{
			if (linkBarGroup)
			{
				linkBarGroup.mxmlContent = value;
				linkBarGroupProperties = BitFlagUtil.update(linkBarGroupProperties as uint, 
					LINKBAR_PROPERTY_FLAG, true);
			}
			else
				linkBarGroupProperties.linkBarContent = value;
		}
		
		//----------------------------------
		//  controlBarLayout
		//---------------------------------- 
		
		/**
		 *  An optional Layout assigned to the control bar.
		 *  
		 *  @langversion 3.0
		 *  @playerversion Flash 10
		 *  @playerversion AIR 1.5
		 *  @productversion Flex 4
		 */
		public function get linkBarLayout():LayoutBase
		{
			return (linkBarGroup) 
			? linkBarGroup.layout 
				: linkBarGroupProperties.layout;
		}
		
		public function set linkBarLayout(value:LayoutBase):void
		{
			if (linkBarGroup)
			{
				linkBarGroup.layout = value;
				linkBarGroupProperties = BitFlagUtil.update(linkBarGroupProperties as uint, 
					LAYOUT_PROPERTY_FLAG, true);
			}
			else
				linkBarGroupProperties.layout = value;
		}
		
		
		/**
		 *  @private
		 */
		override protected function partAdded(partName:String, instance:Object):void
		{
			super.partAdded(partName, instance);
			
			if (instance == linkBarGroup)
			{
				// copy proxied values from linkBarGroupProperties (if set) to contentGroup
				var newlinkBarGroupProperties:uint = 0;
				
				if (linkBarGroupProperties.linkBarContent !== undefined)
				{
					linkBarGroup.mxmlContent = linkBarGroupProperties.linkBarContent;
					newlinkBarGroupProperties = BitFlagUtil.update(newlinkBarGroupProperties, 
						LINKBAR_PROPERTY_FLAG, true);
				}
				
				if (linkBarGroupProperties.layout !== undefined)
				{
					linkBarGroup.layout = linkBarGroupProperties.layout;
					newlinkBarGroupProperties = BitFlagUtil.update(newlinkBarGroupProperties, 
						LAYOUT_PROPERTY_FLAG, true);
				}
				
				linkBarGroupProperties = newlinkBarGroupProperties;
			}
		}
		
		/**
		 *  @inheritDoc
		 *  
		 *  @langversion 3.0
		 *  @playerversion Flash 10
		 *  @playerversion AIR 1.5
		 *  @productversion Flex 4
		 */
		override protected function partRemoved(partName:String, instance:Object):void
		{
			super.partRemoved(partName, instance);
			
			if (instance == linkBarGroup)
			{
				// copy proxied values from contentGroup (if explicitely set) to contentGroupProperties
				
				var newlinkBarGroupProperties:Object = {};
				
//				if (BitFlagUtil.isSet(linkBarGroupProperties as uint, LINKBAR_PROPERTY_FLAG))
//					newlinkBarGroupProperties.linkBarContent = linkBarGroup.getMXMLContent();
				
				if (BitFlagUtil.isSet(linkBarGroupProperties as uint, LAYOUT_PROPERTY_FLAG))
					newlinkBarGroupProperties.layout = linkBarGroup.layout;
				
				linkBarGroupProperties = newlinkBarGroupProperties;
				
				linkBarGroup.mxmlContent = null;
				linkBarGroup.layout = null;
			}
		}
		
		/**
		 *  @inheritDoc
		 *  
		 *  @langversion 3.0
		 *  @playerversion Flash 10
		 *  @playerversion AIR 1.5
		 *  @productversion Flex 4
		 */
		override protected function getCurrentSkinState():String
		{
			var state:String = enabled ? "normal" : "disabled";
			if (linkBarGroup)
			{
				if (BitFlagUtil.isSet(linkBarGroupProperties as uint, LINKBAR_PROPERTY_FLAG))
					state += "WithControlBar";
			}
			else
			{
				if (linkBarGroupProperties.linkBarContent)
					state += "WithControlBar";
			}
			
			return state;
		}

	}
}